﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZSZ.DTO;
using ZSZ.Iservice;
using ZSZ.Service.Entity;

namespace ZSZ.Service
{
    public class HouseService : IHouseService
    {
        public long AddNew(HouseDTO house)
        {
            using (ZSZDBcontext ct = new ZSZDBcontext())
            {
                HouseEntity entity = new HouseEntity();
                entity.Address = house.Address;
                entity.Area = house.Area;
                entity.CheckInDateTime = house.CheckInDateTime;
                entity.CommunityId = house.CommunityId;
                entity.DecorateStatusId = house.DecorateStatusId;
                entity.Description = house.Description;
                entity.FloorIndex = house.FloorIndex;
                entity.LookableDateTime = house.LookableDateTime;
                entity.MonthRent = house.MonthRent;
                entity.OwnerName = house.OwnerName;
                entity.OwnerPhoneNum = house.OwnerPhoneNum;
                entity.RommTypeId = house.RoomTypeId;
                entity.StatusId = house.StatusId;
                entity.TotalFloorCount = house.TotalFloorCount;
                entity.TypeId = house.TypeId;
                var atts = ct.Attachments.AsNoTracking().Where(a => house.AttachmentIds.Contains(a.Id) && a.IsDeleted == false);
                foreach (var item in atts)
                {
                    entity.Attachments.Add(item);
                }
                ct.Houses.Add(entity);
                ct.SaveChanges();
                return entity.Id;
            }
        }

        public long AddNewHousePic(HousePicDTO housePic)
        {
            using (ZSZDBcontext ct = new ZSZDBcontext())
            {
                HousePicEntity en = new HousePicEntity();
                en.HouseId = housePic.HouseId;
                en.ThumbUrl = housePic.ThumbUrl;
                en.Url = housePic.Url;
                ct.HousePics.Add(en);
                ct.SaveChanges();
                return en.Id;
            }
        }

        public void DeleteHousePic(long housePicId)
        {
            using (ZSZDBcontext ct = new ZSZDBcontext())
            {
                CommonService<HousePicEntity> cs = new CommonService<HousePicEntity>(ct);
                var pic = cs.GetById(housePicId);
                ct.HousePics.Remove(pic);
                ct.SaveChanges();
            }
        }
        private HouseDTO ToHouseDTO(HouseEntity e)
        {
            HouseDTO dto = new HouseDTO();
            dto.Address = e.Address;
            dto.Area = e.Area;
            dto.AttachmentIds = e.Attachments.Select(a => a.Id).ToArray();
            dto.CheckInDateTime = e.CheckInDateTime;
            dto.CityId = e.Community.Region.CityId;
            dto.CityName = e.Community.Region.City.Name;
            dto.CommunityBuiltYear = e.Community.BuiltYear;
            dto.CommunityId = e.CommunityId;
            dto.CommunityLocation = e.Community.Location;
            dto.CommunityName = e.Community.Name;
            dto.CommunityTraffic = e.Community.Traffic;
            dto.CreateTime = e.CreateDatatime;
            dto.DecorateStatusId = e.DecorateStatusId;
            dto.DecorateStatusName = e.DecorateStatus.Name;
            dto.Description = e.Description;
            dto.Direction = e.Direction;
            var firstPic = e.HousePics.FirstOrDefault();
            if (firstPic != null)
            {
                dto.FirstThumbUrl = firstPic.ThumbUrl;
            }
            dto.FloorIndex = e.FloorIndex;
            dto.Id = e.Id;
            dto.LookableDateTime = e.LookableDateTime;
            dto.MonthRent = e.MonthRent;
            dto.OwnerName = e.OwnerName;
            dto.OwnerPhoneNum = e.OwnerPhoneNum;
            dto.RegionId = e.Community.RegionId;
            dto.RegionName = e.Community.Region.Name;
            dto.RoomTypeId = e.RommTypeId;
            dto.RoomTypeName = e.RoomType.Name;
            dto.Status = e.Status.Name;
            dto.StatusId = e.StatusId;
            dto.TotalFloorCount = e.TotalFloorCount;
            dto.TtypeName = e.Type.Name;
            dto.TypeId = e.TypeId;
            return dto;
        }
        public HouseDTO GetById(long id)
        {
            using (ZSZDBcontext ct = new ZSZDBcontext())
            {
                CommonService<HouseEntity> cs = new CommonService<HouseEntity>(ct);
                if (!cs.GetAll().Any(h => h.Id == id))
                {
                    throw new ArgumentException("没有这个房子");
                }
                return ToHouseDTO(cs.GetAll().Include(h => h.Attachments).Include(h => h.Community).Include(h => h.Community.Region).Include(h => h.Community.Region.City)
                    .Include(h => h.DecorateStatus).Include(h => h.HousePics).Include(h => h.RoomType).Include(h => h.Status).Include(h => h.Type).SingleOrDefault(h => h.Id == id)
                    );
            }
        }

        public int GetCount(long cityId, DateTime startDateTime, DateTime endDatetiom)
        {
            using (ZSZDBcontext ct = new ZSZDBcontext())
            {
                CommonService<HouseEntity> cs = new CommonService<HouseEntity>(ct);
                return cs.GetAll().Where(h => h.Community.Region.CityId == cityId && h.CreateDatatime >= startDateTime && h.CreateDatatime <= endDatetiom).Count();
            }
        }

        public HouseDTO[] GetPagedData(long cityId, long typeId, int pageSzie, int currentIndex)
        {
            using (ZSZDBcontext ct = new ZSZDBcontext())
            {
                CommonService<HouseEntity> cs = new CommonService<HouseEntity>(ct);
                return cs.GetAll().Include(h => h.Attachments).Include(h => h.Community).Include(h => h.Community.Region).Include(h => h.Community.Region.City)
                     .Include(h => h.DecorateStatus).Include(h => h.HousePics).Include(h => h.RoomType).Include(h => h.Status).Include(h => h.Type)
                     .AsNoTracking()
                     .Where(h => h.Community.Region.CityId == cityId && h.TypeId == typeId)
                     .OrderByDescending(h => h.CreateDatatime).Skip((currentIndex * 10) * (currentIndex - 1)).Take(pageSzie).ToList().Select(h => ToHouseDTO(h)).ToArray();
            }
        }
        private HousePicDTO ToHousepicDTO(HousePicEntity e)
        {
            HousePicDTO dto = new HousePicDTO();
            dto.CreateTime = e.CreateDatatime;
            dto.HouseId = e.HouseId;
            dto.Id = e.Id;
            dto.ThumbUrl = e.ThumbUrl;
            dto.Url = e.Url;
            return dto;
        }
        public HousePicDTO[] GetPics(long houseId)
        {
            using (ZSZDBcontext ct = new ZSZDBcontext())
            {
                CommonService<HousePicEntity> cs = new CommonService<HousePicEntity>(ct);
                return cs.GetAll().Where(h => h.HouseId == houseId).AsNoTracking().ToList().Select(h => ToHousepicDTO(h)).ToArray();
            }
        }

        public long GetTotalCount(long typeId, long cityId)
        {
            using (ZSZDBcontext ct = new ZSZDBcontext())
            {
                CommonService<HouseEntity> cs = new CommonService<HouseEntity>(ct);
                return cs.GetAll().LongCount(h => h.TypeId == typeId && h.Community.Region.CityId == cityId);
            }
        }

        public void MarkDeleted(long id)
        {
            using (ZSZDBcontext ct = new ZSZDBcontext())
            {
                CommonService<HouseEntity> cs = new CommonService<HouseEntity>(ct);
                cs.MarkDeleted(id);
            }
        }

        public HouseSearchResult Search(HouseSearchOptions options)
        {
            using (ZSZDBcontext ct = new ZSZDBcontext())
            {
                CommonService<HouseEntity> cs = new CommonService<HouseEntity>(ct);
                var houses = cs.GetAll().Where(h => h.Community.Region.CityId == options.CityId && h.TypeId == options.TypeId).Include(h => h.Community).Include(h => h.Community.Region).Include(h => h.Community.Region.City)
                    .Include(h => h.DecorateStatus).Include(h => h.HousePics).Include(h => h.RoomType).Include(h => h.Status).Include(h => h.Type)
                     .AsNoTracking();
                if (options.RegionId!=null)
                {
                    houses = houses.Where(h=>h.Community.RegionId==options.RegionId);
                }
                if (options.StartMonthRent!=null)
                {
                    houses = houses.Where(h => h.MonthRent>=options.StartMonthRent);
                }
                if (options.EndMonthRent != null)
                {
                    houses = houses.Where(h => h.MonthRent <= options.EndMonthRent);
                }
                if (options.Keywords!=null)
                {
                    houses = houses.Where(h=>h.Direction.Contains(options.Keywords)||h.Community.Location.Contains(options.Keywords));
                }
                long count = houses.LongCount();
                switch (options.OrderByType)
                {
                    case OrderByType.MonthRentDesc:
                        houses = houses.OrderByDescending(h=>h.MonthRent);
                        break;
                    case OrderByType.MonthRentAsc:
                        houses = houses.OrderBy(h => h.MonthRent);
                        break;
                    case OrderByType.AreaDesc:
                        houses = houses.OrderByDescending(h => h.Area);
                        break;
                    case OrderByType.AreaAsc:
                        houses = houses.OrderBy(h => h.Area);
                        break;
                    case OrderByType.CreateDateDesc:
                        houses = houses.OrderByDescending(h => h.CreateDatatime);
                        break;
                    default:
                        houses = houses.OrderBy(h => h.CreateDatatime);
                        break;
                }
                houses = houses.Skip((options.CurrentIndex-1)*10).Take(10);
                HouseSearchResult result = new HouseSearchResult();
                result.result = houses.ToList().Select(h => ToHouseDTO(h)).ToArray();
                result.totalCount = count;
                return result;
            }
        }

        public void Update(HouseDTO house)
        {
            using (ZSZDBcontext ct = new ZSZDBcontext())
            {
                CommonService<HouseEntity> cs = new CommonService<HouseEntity>(ct);
                HouseEntity entity = cs.GetById(house.Id);
                entity.Address = house.Address;
                entity.Area = house.Area;
                entity.Attachments.Clear();
                var attach = ct.Attachments.Where(a => a.IsDeleted == false && house.AttachmentIds.Contains(a.Id));
                foreach (var item in attach)
                {
                    entity.Attachments.Add(item);
                }
                entity.CheckInDateTime = house.CheckInDateTime;
                entity.CommunityId = house.CommunityId;
                entity.DecorateStatusId = house.DecorateStatusId;
                entity.Description = house.Description;
                entity.Direction = house.Direction;
                entity.FloorIndex = house.FloorIndex;
                entity.LookableDateTime = house.LookableDateTime;
                entity.MonthRent = house.MonthRent;
                entity.OwnerName = house.OwnerName;
                entity.OwnerPhoneNum = house.OwnerPhoneNum;
                entity.RommTypeId = house.RoomTypeId;
                entity.StatusId = house.StatusId;
                entity.TotalFloorCount = house.TotalFloorCount;
                ct.SaveChanges();
            }
        }
    }
}
